/* ****************************************************************************
 *
 * Copyright (c) Microsoft Corporation. 
 *
 * This source code is subject to terms and conditions of the Microsoft Public License. A 
 * copy of the license can be found in the License.html file at the root of this distribution. If 
 * you cannot locate the  Microsoft Public License, please send an email to 
 * dlr@microsoft.com. By using this source code in any fashion, you are agreeing to be bound 
 * by the terms of the Microsoft Public License.
 *
 * You must not remove this notice, or any other, from this software.
 *
 * THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
 * KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
 * PARTICULAR PURPOSE.
 * ***************************************************************************/


#include "stdafx.h"
#include "pgldemo.h"

IMPLEMENT_DYNCREATE(CPGLDemo,CObject);


CPGLDemo::VectorPairDIDef CPGLDemo::m_vPairs;

void CPGLDemo::GetExampleBar(CPGLRegionPtr pRegion)
{
	using namespace Gdiplus;

	ASSERT(pRegion);
	UINT n = 5, np;
	UINT i,j;
	CString str;

	pRegion->SetName(_T("Bars"));
	pRegion->Divide(2,1);

	///////////////////////////////////////////////////////
	// Stacked bar graph
	CPGLRegionPtr pChildRegion = pRegion->GetChild(0);
	CPGLAxe2D* pAxis = pChildRegion->GetAxe();
	pAxis->SetTitle(_T("Stacked bar graph with specified x positions"));

	CPGLBar* pBar = new CPGLBar( CPGLBar::ETypeStacked);
	np=6;

	CPGLLine1D* pLine;
	CPGLVectorF* pData;
	CPGLColor col,white(1,1,1,0.2f);
	col.SetAlpha(0.8f);

	std::vector<float> vXs(np);
	std::vector<float> vYs(np,0);
	for (i=0;i<np;i++)
	{
//		vXs[i] = 5+pow(i*2.5,3/2.0);
		vXs[i] = (REAL)i;
	}

	pBar->SetXPositions( new CPGLVectorF( vXs ) );

	for (i=0;i<n;i++)
	{
		pLine = new CPGLLine1D;
		pData = new CPGLVectorF(np);
		std::vector<float>& vData = pData->GetV();

		CPGLUtility::HSV(i/(double)n,col);
		col.SetAlpha(0.8f);
		pLine->SetSolidFillColor( col );

		for (j=0;j<np;j++)
		{
			vData[j]=(REAL)(j+5*rand() / (double)RAND_MAX);
			vYs[j]+=(REAL)(vData[j]);
		}
		pLine->SetValues(pData);
		pBar->PushFront(pLine);
	}

	pChildRegion->AddObject(pBar);

	CPGLLine2D* pLine2D = new CPGLLine2D;
	pLine2D->SetDatas(vXs, vYs);
	pLine2D->SetName(_T("A dummy line"));
	pLine2D->SetLineWidth(2);
	pLine2D->SetMarkerType( CPGLLine::MarkerTypeCircle );
	pLine2D->SetMarkerWidth( 3 );
	pChildRegion->AddObject(pLine2D);

	/////////////////////////////////////////////////////////
	// Side by side bar graph
	pChildRegion = pRegion->GetChild(1);
	pAxis = pChildRegion->GetAxe();
	pAxis->SetTitle(_T("Side by side bar graph"));

	pBar = new CPGLBar( CPGLBar::ETypeSideBySide);
	pBar->SetPixelInter(20);

	np=5;
	for (i=0;i<n;i++)
	{
		pLine = new CPGLLine1D;
		str.Format( _T("data serie %u"),i);
		pLine->SetName( str );
		pData = new CPGLVectorF(np);
		std::vector<float>& vData = pData->GetV();

		CPGLUtility::HSV(i/(double)n,col);
		pLine->SetBrush( new CPGLLinearGradientBrush(col, white, 90) );

		for (j=0;j<np;j++)
		{
			vData[j] =(REAL)( 10+90*sin(j*PGL_PI/4+i*PGL_PI/8)*sin(j*PGL_PI/4+i*PGL_PI/8)+5*rand() / (double)RAND_MAX);
		}
		pLine->SetValues(pData);
		pBar->PushFront(pLine);
	}

	pChildRegion->AddObject(pBar);
	pChildRegion->AddLegend();
}


void CPGLDemo::GetExampleLineInterpolation(CPGLRegionPtr pRegion)
{
	ASSERT(pRegion);

	pRegion->SetName(_T("Different types of line interpolation"));
	
	// generate data
	double x;
	UINT nPoints = 42;
	std::vector<double> vX(nPoints);
	std::vector<double> vY(nPoints);
	for (UINT i=0;i<nPoints;i++)
	{
		vX[i]=i/(double)nPoints;
		vY[i]=1+pow(sin(i/(double)nPoints*2*3.14)*1.1,2);
	}

	CPGLLinearGradientBrush* brush = new CPGLLinearGradientBrush(CPGLColor(0,0.7f,0), CPGLColor(1,1,1),90);

	//Create a 2D line:
	CPGLLine2D* pLine = new CPGLLine2D();

	/*Attach the data to the line. PGL will handle the memory afterwards. That is, it will delete 
	the pointers of data at the object destruction. This means <code>pX,pY</code> MUST have been 
	allocated on the heap !
	*/
	pLine->SetDatas( vX /* x(i) */, vY /* y(i) */);

	//(Optional)Change some properties of the line:
	pLine->SetLineWidth(2);
	pLine->SetBrush(brush);
	pLine->SetFilled(true);
	pLine->SetSnapBottom(true);
	pLine->SetName(_T("Default"));
	//Add the line to the graph (note that an object can be added to only one graph):
	pRegion->AddObject(pLine);

	//Create a 2D line:
	pLine = new CPGLLine2D();
	x= vX[nPoints-1];
	for (i=0;i<nPoints;i++)
	{
		vX[i]=x+(i+1)/(double)nPoints;
		vY[i]=1+pow(sin(i/(double)nPoints*2*3.14)*1.1,2);
	}

	pLine->SetDatas( vX /* x(i) */, vY /* y(i) */);

	brush = new CPGLLinearGradientBrush(CPGLColor(0.6f,0,0), CPGLColor(1,1,1),90);
	pLine->SetLineWidth(2);
	pLine->SetBrush(brush);
	pLine->SetFilled(true);
	pLine->SetSnapBottom(true);
	pLine->SetName(_T("Step"));
	pLine->SetInterpolationType( CPGLLine::InterpolationTypeStep );
	//Add the line to the graph (note that an object can be added to only one graph):
	pRegion->AddObject(pLine);

	//Create a 2D line:
	pLine = new CPGLLine2D();
	x= vX[nPoints-1];
	nPoints=10;
	vX.resize(5*nPoints);
	vY.resize(5*nPoints);
	for (int k=0;k<5;k++)
	{
		for (i=0;i<nPoints;i++)
		{
			vX[k*nPoints+i]=x+(i+1+3*k)/(double)(2*nPoints);
			vY[k*nPoints+i]=1+pow(sin((i/(double)nPoints+k/10.0)*3.14)*1.1,2);
		}
	}

	pLine->SetDatas( vX /* x(i) */, vY /* y(i) */);

	brush = new CPGLLinearGradientBrush(CPGLColor(0.6f,0,0), CPGLColor(1,1,1),90);
	pLine->SetLineWidth(2);
	pLine->SetName(_T("Multiple line strip"));
	pLine->SetInterpolationType( CPGLLine::InterpolationTypeSegment );
	pLine->SetStripSize(nPoints);
	pLine->SetShadowing(true);
	//Add the line to the graph (note that an object can be added to only one graph):
	pRegion->AddObject(pLine);
	pRegion->GetAxe()->SetTitle(_T("Types of line interpolation"));

	pRegion->AddLegend();
}

void CPGLDemo::GetExampleStock(CPGLRegionPtr pRegion)
{
	using namespace Gdiplus;

	COleDateTime tStart(2000,1,1,8,0,0);
	COleDateTimeSpan oneday(1,0,0,0); 
	COleDateTimeSpan dt;

	ASSERT_VALID(pRegion);
	pRegion->SetName(_T("Open - High - Low - Close"));

	// generating data
	srand( (unsigned)time( NULL ) );
	UINT nPoints = 60;
	std::vector<float> vHis(nPoints);
	std::vector<float> vLows(nPoints);
	std::vector<float> vCloses(nPoints);
	std::vector<float> vOpens(nPoints);

	vCloses[0]=vOpens[0]=1.5;
	vHis[0]=(REAL)(vCloses[0]+rand()/(double)RAND_MAX*0.3);
	vLows[0]=(REAL)(vCloses[0]- rand()/(double)RAND_MAX*0.3);
	for (UINT i=1;i<nPoints;i++)
	{
		vCloses[i]=(REAL)(1.5+sin(i/(double)nPoints*2*3.14)+rand()/(double)RAND_MAX*0.3);
		vOpens[i]=(REAL)(vCloses[i-1]+rand()/(double)RAND_MAX*0.05);
		vHis[i]=(REAL)(__max(vOpens[i],vCloses[i])+rand()/(double)RAND_MAX*0.3);
		vHis[i]=(REAL)(__max(vCloses[i-1], vHis[i]));
		vLows[i]=(REAL)(__min(vOpens[i],vCloses[i])- rand()/(double)RAND_MAX*0.3);
		vLows[i]=(REAL)(__min(vCloses[i-1], vLows[i]));
	}

	// create and add line
	CPGLStock* pStock = new CPGLStock;
	pStock->SetDatas(vHis, vLows, vOpens, vCloses);
	pStock->SetX0(0);
	pStock->SetDx(1);
	pStock->SetLineWidth(1);
	pStock->SetUpColor(CPGLColor(0,0,0.7f));
	pStock->SetDownColor(CPGLColor(0.7f,0,0));
	pStock->SetType( CPGLStock::TypeOpenHighLowClose);
	pRegion->AddObject(pStock);

	// generating other data set
	vCloses[0]=vOpens[0]=3;
	vHis[0]=(REAL)(vCloses[0]+rand()/(double)RAND_MAX*0.3);
	vLows[0]=(REAL)(vCloses[0]- rand()/(double)RAND_MAX*0.3);
	for (i=1;i<nPoints;i++)
	{
		vCloses[i]=(REAL)(3+sin(i/(double)nPoints*2*3.14)+rand()/(double)RAND_MAX*0.3);
		vOpens[i]=(REAL)(vCloses[i-1]+rand()/(double)RAND_MAX*0.05);
		vHis[i]=(REAL)(__max(vOpens[i],vCloses[i])+rand()/(double)RAND_MAX*0.3);
		vHis[i]=(REAL)(__max(vCloses[i-1], vHis[i]));
		vLows[i]=(REAL)(__min(vOpens[i],vCloses[i])- rand()/(double)RAND_MAX*0.3);
		vLows[i]=(REAL)(__min(vCloses[i-1], vLows[i]));
	}
	
	// create and add line
	pStock = new CPGLStock;
	pStock->SetDatas(vHis, vLows, vOpens, vCloses);
	pStock->SetX0(0);
	pStock->SetDx(1);
	pStock->SetLineWidth(1);
	pStock->SetUpColor(CPGLColor(0,0,0));
	pStock->SetDownColor(CPGLColor(0,0,0));
	pStock->SetType( CPGLStock::TypeCandleStick);
	pRegion->AddObject(pStock);

	// configuration axis
	CPGLAxe2D* pAxis = pRegion->GetAxe();
	pAxis->SetTitle(_T("Stocks demo"));
	pAxis->GetLeftLabel().Hide();
	pAxis->GetBottomLabel().Hide();
	// setting time label
	pAxis->SetTimeLabel(TRUE);
	pAxis->SetTimeLabelFormat(tStart
		 /* Time at coordinate zero. */, 
			oneday	/* Time per unit */,
			_T("%B, %Y") /* String format */);
	pAxis->GetBottomNumber().SetAngle(-45);
	pAxis->GetBottomNumber().SetAlign(gfxinterface::TextAlignmentLeft);
	CPGLLinearGradientBrush* brush = new CPGLLinearGradientBrush( CPGLColor(0.6f,0.6f,0.8f), CPGLColor(1,1,1,1), 90);
	pAxis->SetBrush(brush);

	// fixing step
	pAxis->SetAutoSteps(CPGLAxe2D::AxisHorizontal,false);
	pAxis->SetGridStep(CPGLAxe2D::AxisHorizontal, 31);	

	// setting background...
	pRegion->SetBorderType(CPGLPave::BorderLowerRightShadow);
	CPGLLinearGradientBrush* rbrush = new CPGLLinearGradientBrush( CPGLColor(0.5,0.8f,0.8f), CPGLColor(1,1,1,1), 45);
	pRegion->SetBrush(rbrush);	
}

void CPGLDemo::GetExampleContainer(CPGLRegionPtr pRegion)
{
	ASSERT_VALID(pRegion);

	pRegion->SetName(_T("Chart container"));

	std::vector<double> vXs(4);
	std::vector<double> vYs(4);
	vXs[0]=0;vXs[1]=1;vXs[2]=1;vXs[3]=0;
	vYs[0]=0;vYs[1]=0;vYs[2]=1;vYs[3]=1;

	// normalized square
	CPGLLine2D* pLine = new CPGLLine2D;
	pLine->SetDatas( vXs, vYs);
	pLine->SetSolidFillColor(CPGLColor::GetClassicColor( CPGLColor::Green ) );
	pLine->SetFilled(true);
	pLine->SetOpen(false);
	pLine->SetName(_T("Original object"));
	pRegion->AddObject( pLine );

	// rotated normalize square
	pLine = new CPGLLine2D;
	pLine->SetDatas( vXs, vYs);
	pLine->SetSolidFillColor( CPGLColor::GetClassicColor( CPGLColor::Blue ) );
	pLine->SetFilled(true);
	pLine->SetName(_T("Rotated object"));
	pLine->SetOpen(false);


	CPGLContainer* pContainer = new CPGLContainer;
	pRegion->AddObject( pContainer );
	pContainer->AddObjectHead( pLine );
	pContainer->PushRotation( PGL_PI/4.0, CPGLPointD(0.5, 0.5) );
	pContainer->SetName(_T("Container"));

	CPGLAxe2D* pAxis = pRegion->GetAxe();
	pAxis->SetTitle(_T("Container demo"));
	pAxis->SetSquare(true);
	
	pRegion->AddLegend();
}

void CPGLDemo::GetExampleScatter(CPGLRegionPtr pRegion)
{
	using namespace std;

	ASSERT_VALID(pRegion);
	pRegion->SetName(_T("Scatters of points"));

	CPGLScatter* pScatter;
	float x,y,v;
	CString str;
	const UINT nPoints = 500;
	UINT i;
	srand( (unsigned)time( NULL ) );

	// circle scatter
	pScatter = new CPGLScatter;
	CPGLVectorF* pX =new CPGLVectorF(nPoints);
	CPGLVectorF* pY =new CPGLVectorF(nPoints);
	CPGLVectorF* pValues =new CPGLVectorF(nPoints);
	pScatter->SetDatas(pX,pY,pValues);


	pScatter->SetMinValue(0);
	pScatter->SetMaxValue(1);
	pScatter->SetColorMap(CPGLUtility::ColorMapJet);

	{
		vector<float>& vX=pX->GetV();
		vector<float>& vY=pY->GetV();
		vector<float>& vValues=pValues->GetV();
		for (i=0;i< nPoints;i++)
		{
			x=(float)(5*pow(rand()/(double)RAND_MAX,2));
			y=(float)(100*rand()/(double)RAND_MAX);
			v=(float)(x/10.0+y/200.0+( rand()/(double)RAND_MAX-0.5 )*0.3);
			vX[i]=x; vY[i]=y; vValues[i]=v;
		}
	}
	pScatter->SetMarkerWidth(4);
	pScatter->SetMarkerType( CPGLScatter::MarkerTypeCircle);
	pRegion->AddObject(pScatter);

	// another scatter, triangle
	pScatter = new CPGLScatter;
	pX =new CPGLVectorF(nPoints);
	pY =new CPGLVectorF(nPoints);
	pValues =new CPGLVectorF(nPoints);
	pScatter->SetDatas(pX,pY,pValues);

	pScatter->SetMinValue(0);
	pScatter->SetMaxValue(1);
	pScatter->SetColorMap(CPGLUtility::ColorMapJet);

	{
		vector<float>& vX=pX->GetV();
		vector<float>& vY=pY->GetV();
		vector<float>& vValues=pValues->GetV();
		for (i=0;i< nPoints;i++)
		{
			x=5+(float)(5*pow(rand()/(double)RAND_MAX,2));
			y=(float)(100*rand()/(double)RAND_MAX);
			v=(float)((x-5)/10.0+y/200.0+( rand()/(double)RAND_MAX-0.5 )*0.3);
			vX[i]=x; vY[i]=y; vValues[i]=v;
		}
	}
	pScatter->SetMarkerWidth(5);
	pScatter->SetMarkerType( CPGLScatter::MarkerTypeTriangle);
	pScatter->SetColorMap( CPGLUtility::ColorMapBone);
	pRegion->AddObject(pScatter);

	// another scatter, square
	pScatter = new CPGLScatter;
	pX =new CPGLVectorF(nPoints);
	pY =new CPGLVectorF(nPoints);
	pValues =new CPGLVectorF(nPoints);
	pScatter->SetDatas(pX,pY,pValues);

	pScatter->SetMinValue(0);
	pScatter->SetMaxValue(1);
	pScatter->SetColorMap(CPGLUtility::ColorMapJet);
	{
		vector<float>& vX=pX->GetV();
		vector<float>& vY=pY->GetV();
		vector<float>& vValues=pValues->GetV();
		for (i=0;i< nPoints;i++)
		{
			x=(float)(5*pow(rand()/(double)RAND_MAX,2));
			y=100+(float)(100*rand()/(double)RAND_MAX);
			v=(float)(x/10.0+(y-100)/200.0+( rand()/(double)RAND_MAX-0.5 )*0.3);
			vX[i]=x; vY[i]=y; vValues[i]=v;
		}
	}
	pScatter->SetMarkerWidth(5);
	pScatter->SetMarkerType( CPGLScatter::MarkerTypeSquare);
	pScatter->SetColorMap( CPGLUtility::ColorMapAutumn);
	pRegion->AddObject(pScatter);

	// another scatter
	pScatter = new CPGLScatter;
	pX =new CPGLVectorF(nPoints);
	pY =new CPGLVectorF(nPoints);
	pValues =new CPGLVectorF(nPoints);
	pScatter->SetDatas(pX,pY,pValues);

	pScatter->SetMinValue(0);
	pScatter->SetMaxValue(1);
	pScatter->SetColorMap(CPGLUtility::ColorMapJet);
	{
		vector<float>& vX=pX->GetV();
		vector<float>& vY=pY->GetV();
		vector<float>& vValues=pValues->GetV();
		for (i=0;i< nPoints;i++)
		{
			x=5+(float)(5*pow(rand()/(double)RAND_MAX,2));
			y=100+(float)(100*rand()/(double)RAND_MAX);
			v=(float)((x-5)/10.0+(y-100)/200.0+( rand()/(double)RAND_MAX-0.5 )*0.3);
			vX[i]=x; vY[i]=y; vValues[i]=v;
		}
	}
	pScatter->SetMarkerWidth(5);
	pScatter->SetMarkerType( CPGLScatter::MarkerTypeText);
	pScatter->SetColorMap( CPGLUtility::ColorMapJet);
	pScatter->SetString(_T(":)"));
	pScatter->SetMarkerWidth(8);
	pScatter->GetMarkerText().SetAngle(-90);
	pRegion->AddObject(pScatter);

	// configuration axis
	CPGLAxe2D* pAxis = pRegion->GetAxe();
	str.Format(_T("Scatter demo (%d points)"), nPoints);
	pAxis->SetTitle(str);
	pAxis->GetLeftLabel().Hide();
	pAxis->GetBottomLabel().Hide();
}


void CPGLDemo::GetExamplePie(CPGLRegionPtr pRegion)
{
	ASSERT_VALID(pRegion);
	pRegion->SetName(_T("Pie and donnut"));
	
	CPGLColor col;
	CPGLPie* pPie;
	CPGLPieData* pData;
	CString str;
	int n;

	/////////////////////////////
	// first pie
	pPie = new CPGLPie;
	pPie->SetName(_T("Main Pie"));
	n=5;
	for (int i=0;i<n;i++)
	{
		pData=new CPGLPieData((i/(double)2+1)*(double)10);
		if (i%3==0)
			pData->SetExploded(true);
		pPie->PushBack(pData);
		str.Format(_T("Data set %d"),i);
		pData->SetName(str);
	}
	pRegion->AddObject(pPie);
	pPie->SetExplodedRadiusPixel(20);
	pPie->SetAutoColoring(true);
	pPie->SetRadius(0.35);
	pPie->SetCenter(CPGLPointD(0.36,0.36));

	pRegion->AddLegend();

	/////////////////////////////
	// second pie
	pPie = new CPGLPie;
	pPie->SetName(_T("Second Pie"));
	n=10;
	for (i=0;i<n;i++)
	{
		pData=new CPGLPieData((i/(double)3+1)*(double)n);
		pData->SetExploded(true);
		pPie->PushBack(pData);
		str.Format(_T("Second Data set %d"),i);
		pData->SetName(str);
	}
	pRegion->AddObject(pPie);
	pPie->SetAutoColoring(true);
	pPie->SetExplodedRadiusPixel(10);
	pPie->SetColorMap(CPGLUtility::ColorMapHsv);
	pPie->SetRadius(0.2);
	pPie->SetInsideRadius(0.1);
	pPie->SetCenter(CPGLPointD(0.75,0.7));
	pPie->SetAlpha(0.8);
	pPie->GetValuesText().Hide();
	
	CPGLLinearGradientBrush* brush=  new CPGLLinearGradientBrush(CPGLColor(1,1,0,1), CPGLColor(1,1,1,1),45);
	pRegion->SetBrush(brush);	
	pRegion->SetBorderType(CPGLPave::BorderLowerRightShadow);

	CPGLAxe2D* pAxis = pRegion->GetAxe();
	pAxis->Hide();
}

void CPGLDemo::GetExampleSplines(CPGLRegionPtr pRegion)
{
	using namespace std;
	ASSERT(pRegion);
	CPGLLine2D* pLine;
	pRegion->SetName(_T("Spline tension"));

	UINT nPoints = 5;
	vector<float> vX(nPoints);
	vector<float> vY(nPoints);
	
	for (UINT i=0;i<nPoints;i++)
	{
		vX[i]=(float)i;
		vY[i]=(float)cos(i*PGL_PI);
	}

	pLine= new CPGLLine2D;
	pLine->SetInterpolationType(CPGLLine::InterpolationTypeSpline);
	pLine->SetTension(0);
	pLine->SetDatas(vX,vY);
	pLine->SetName(_T("Tension = 0"));
	pLine->SetLineWidth(2); 
	pLine->SetColor(1,0,0);
	pRegion->AddObject(pLine);

	pLine= new CPGLLine2D;
	pLine->SetInterpolationType(CPGLLine::InterpolationTypeSpline);
	pLine->SetTension(0.6);
	pLine->SetDatas(vX,vY);
	pLine->SetName(_T("Tension = 0.6"));
	pLine->SetLineWidth(2); 
	pLine->SetColor(0,1,0);
	pRegion->AddObject(pLine);

	pLine= new CPGLLine2D;
	pLine->SetInterpolationType(CPGLLine::InterpolationTypeSpline);
	pLine->SetTension(1);
	pLine->SetDatas(vX,vY);
	pLine->SetName(_T("Tension = 1"));
	pLine->SetLineWidth(2); 
	pLine->SetColor(0,0,1);
	pRegion->AddObject(pLine);

	pRegion->AddLegend();
	pRegion->GetAxe()->SetTitle(_T("Spline Demo"));
	pRegion->GetAxe()->GetBottomLabel().Hide();
	pRegion->GetAxe()->GetLeftLabel().Hide();
}

void CPGLDemo::GetExampleMultipleAxis(CPGLRegionPtr pRegion)
{
	ASSERT(pRegion);

  pRegion->DeleteAllObjects();
  pRegion->GetAxe()->Hide();
  
	// adding first region
	CPGLRegionPtr pBackChildRegion=pRegion->AddRegion();
	GetExampleLineLOD(pBackChildRegion);
	pBackChildRegion->SetSolidFillColor(1,1,1,0);
	CPGLAxe2D* pBackAxe = pBackChildRegion->GetAxe();
	pBackAxe->SetAutoBorders(CPGLRectB(false, false, false, false));
	pBackAxe->SetBorders(CPGLRectD(40, 40, 50, 40));
	
	  CPGLRegionPtr pFrontChildRegion=pRegion->AddRegion();
	  GetExampleMarkers(pFrontChildRegion);
	  pFrontChildRegion->SetSolidFillColor(1,1,1,0);
	  CPGLAxe2D* pFrontAxe = pFrontChildRegion->GetAxe();
	  pFrontAxe->SetSolidFillColor(1,1,1,0);
	  pFrontAxe->GetTitle().Hide();
	  pFrontAxe->GetTopNumber().Show();
	  pFrontAxe->GetBottomLabel().Hide();
	  pFrontAxe->GetBottomNumber().Hide();
	  pFrontAxe->GetLeftNumber().Hide();
	  pFrontAxe->GetLeftLabel().Hide();
	  pFrontAxe->GetRightLabel().Show();
	  pFrontAxe->GetRightNumber().Show();
	  pFrontAxe->SetAutoBorders(CPGLRectB(false, false, false, false));
	  pFrontAxe->SetBorders(CPGLRectD(40, 40, 50, 40));
	
/*	
	ASSERT(pRegion);
	
	using namespace std;
	using namespace gfxinterface;
	
	CPGLAxe2D* pAxe = pRegion->GetAxe();
	//  pAxe->Hide();
	pAxe->GetTitle()->Hide();
	pAxe->GetBottomLabel()->Hide();
	pAxe->GetBottomNumber()->Hide();
	pAxe->GetLeftNumber()->Hide();
	pAxe->GetLeftLabel()->Hide();
	pAxe->SetAutoBorders(CPGLRectB(false, false, false, false));
	pAxe->SetBorders(CPGLRectD(20, 20, 20, 20));
	pAxe->SetBorderLineVisibility(CPGLRectB(false, false, false, false));
	pAxe->SetShowNumbers(CPGLAxe2D::ENumberingBottom, false);
	pAxe->SetShowNumbers(CPGLAxe2D::ENumberingLeft, false);
	pAxe->SetShowNumbers(CPGLAxe2D::ENumberingRight, false);
	pAxe->SetShowNumbers(CPGLAxe2D::ENumberingTop, false);
	pAxe->SetSolidFillColor(1,1,1,0);
	pAxe->ShowHorGrid(false);
	pAxe->ShowVerGrid(false);
	pAxe->SetAutoSteps(0, false);
	pAxe->SetAutoSteps(1, false);
	//  pRegion->SetSolidFillColor(0.5,0.5,0.5,0);
	
	CPGLLegend* pLegend = new CPGLLegend();
	pLegend->SetPosition( CPGLLegend::LegendPosUpperRight );
	pLegend->GetArea().SetBBTrans( SPointD(-40,-30));
	
	UINT nPoints = 5;
	
	vector<double> vX1(nPoints);
	vector<double> vY1(nPoints);
	
	vector<double> vX2(nPoints);
	vector<double> vY2(nPoints);
	
	for (UINT i=0; i<nPoints; ++i)
	{
		vX1[i]=i;
		vY1[i]=i*i;
		
		vX2[i]=i;
		vY2[i]=10*i;
	}
	
	CPGLRegionPtr pChildRegion;
	CPGLLine2D* pLine;
	
	pChildRegion = pRegion->AddRegion();
	
	pLine = new CPGLLine2D;
	pLine->SetLineWidth(2); 
	pLine->SetColor(1,0,0);
	pLine->SetDatas( vX1, vY1 );
	pLine->SetName(_T("Squares"));
	
	pChildRegion->AddObject(pLine);
	pChildRegion->SetSolidFillColor(1,1,1,0);
	
	pAxe = pChildRegion->GetAxe();
	//  pAxe->GetTitle()->Hide();
	pAxe->SetTitle( _T("Dummy Test") );
	pAxe->SetAutoBorders(CPGLRectB(false, false, false, false));
	pAxe->SetBorders(CPGLRectD(50, 50, 50, 50));
	pAxe->SetLabel( CPGLAxe2D::ELabelLeft, _T("Squares") );
	pAxe->SetAutoSteps(0, false);
	pAxe->SetGridStep(0, 1.0);
	pAxe->GetNumber(CPGLAxe2D::ENumberingLeft)->SetColor(pLine->GetColor());
	
	pChildRegion->GetObjectManager()->PushLinesTop(pLegend);
	
	
	pChildRegion = pRegion->AddRegion();
	
	pLine = new CPGLLine2D;
	pLine->SetDatas( vX2, vY2 );
	pLine->SetName(_T("Doubles"));
	pLine->SetLineWidth(2); 
	pLine->SetColor(0,1,0);
	
	pChildRegion->AddObject(pLine);
	pChildRegion->SetSolidFillColor(1,1,1,0);
	
	pAxe = pChildRegion->GetAxe();
	pAxe->SetSolidFillColor(1,1,1,0);
	
	pAxe->GetTitle()->Hide();
	
	pAxe->GetBottomLabel()->Hide();
	pAxe->GetBottomNumber()->Hide();
	pAxe->GetLeftNumber()->Hide();
	pAxe->GetLeftLabel()->Hide();
	
	pAxe->SetAutoSteps(0, false);
	pAxe->SetGridStep(0, 1.0);
	
	// pAxe->GetTopLabel().Show();
	//  pAxe->GetTopNumber().Show();
	pAxe->GetRightLabel().Show();
	pAxe->GetRightNumber().Show();
	pAxe->SetLabel( CPGLAxe2D::ELabelRight, _T("Doubles") );
	pAxe->GetNumber(CPGLAxe2D::ENumberingRight)->SetColor(pLine->GetColor());
	
	pAxe->SetAutoBorders(CPGLRectB(false, false, false, false));
	pAxe->SetBorders(CPGLRectD(50, 50, 50, 50));
	
	pChildRegion->GetObjectManager()->PushLinesTop(pLegend);
	
	
	pRegion->AddObject(pLegend);
	
	pRegion->SetChildFirst(true);
*/
}


void CPGLDemo::GetExampleMarkers(CPGLRegionPtr pRegion)
{
	using namespace std;
	ASSERT(pRegion);
	CPGLLine2D* pLine;
	pRegion->SetName(_T("Markers"));
	
	UINT nPoints = 25;
	vector<double> vX(nPoints);
	vector<double> vY(nPoints);
	for (UINT i=0;i<nPoints;i++)
	{
		vX[i]=i;
		vY[i]=cos(i*PGL_PI/nPoints);
	}

	pLine= new CPGLLine2D;
	pLine->SetDatas(vX,vY);
	pLine->SetName(_T("Circle"));
	pLine->SetMarkerType(CPGLLine::MarkerTypeCircle);
	pLine->SetMarkerWidth(3);
	pLine->SetLineWidth(2);
	pLine->SetContoured(false); 
	pLine->SetSolidFillColor(1,0,0);
	pRegion->AddObject(pLine);

	for (i=0;i<nPoints;i++)
	{
		vY[i]=cos((i+nPoints/7)*PGL_PI/nPoints);
	}

	pLine= new CPGLLine2D;
	pLine->SetDatas(vX,vY);
	pLine->SetName(_T("Contour and text"));
	pLine->SetMarkerType(CPGLLine::MarkerTypeContour);
	pLine->SetMarkerWidth(4);
	pLine->SetLineWidth(2);
	pLine->SetContoured(false); 
	pLine->SetColor(0.5,0.5,0);
	pLine->GetMarker()->GetTextFormat().Show();
	pRegion->AddObject(pLine);

	for (i=0;i<nPoints;i++)
	{
		vY[i]=cos((i+2*nPoints/7)*PGL_PI/nPoints);
	}

	pLine= new CPGLLine2D;
	pLine->SetDatas(vX,vY);
	pLine->SetName(_T("Triangle"));
	pLine->SetMarkerType(CPGLLine::MarkerTypeTriangle);
	pLine->SetMarkerWidth(4);
	pLine->SetLineWidth(2);
	pLine->SetContoured(false); 
	pLine->SetColor(0,0.5,0.5);
	pRegion->AddObject(pLine);

	for (i=0;i<nPoints;i++)
	{
		vY[i]=cos((i+3*nPoints/7)*PGL_PI/nPoints);
	}

	pLine= new CPGLLine2D;
	pLine->SetDatas(vX,vY);
	pLine->SetName(_T("char"));
	CPGLCharMarker* pCharMarker =new CPGLCharMarker;
	pCharMarker->SetString(_T("@"));
	pLine->SetMarker(pCharMarker);
	pLine->SetMarkerWidth(5);
	pLine->SetLineWidth(2);
	pLine->SetContoured(false); 
	pLine->SetColor(0,0,1);
	pRegion->AddObject(pLine);

	for (i=0;i<nPoints;i++)
	{
		vY[i]=cos((i+4*nPoints/7)*PGL_PI/nPoints);
	}

	// creating custom shape
	pLine= new CPGLLine2D;
	pLine->SetDatas(vX,vY);
	pLine->SetName(_T("Custom"));
	CPGLPolygonMarker* pPolygon = new CPGLPolygonMarker();
	CPGLVectorF* pCornerX=new CPGLVectorF(30);
	CPGLVectorF* pCornerY=new CPGLVectorF(30);
	std::vector<float>& vCornerX=pCornerX->GetV();
	std::vector<float>& vCornerY=pCornerY->GetV();
	double alpha;
	for (i=0;i<vCornerX.size();i++)
	{
		alpha=(double)(i+1)/(double)(vCornerX.size());
		vCornerX[i]=(float)(alpha*cos(alpha*4*PGL_PI));
		vCornerY[i]=(float)(alpha*sin(alpha*4*PGL_PI));
	}

	pPolygon->SetDatas(pCornerX,pCornerY);
	pPolygon->SetRadius(10);	
	pPolygon->SetClosed(false);
	pPolygon->SetShadowing(true);
	pLine->SetLineWidth(2);
	pLine->SetMarker(pPolygon);
	pLine->SetContoured(false); 
	pLine->SetColor(0.2f,0.1f,.5f);
	pRegion->AddObject(pLine);

	// Hexagon
	for (i=0;i<nPoints;i++)
	{
		vY[i]=cos((i+5*nPoints/7)*PGL_PI/nPoints);
	}

	pLine= new CPGLLine2D;
	pLine->SetDatas(vX,vY);
	pLine->SetName(_T("Hexagon"));
	CPGLCircPolygonMarker* pHexagon = CPGLCircPolygonMarker::GetHexagon();
	pLine->SetMarker(pHexagon);
	pHexagon->SetRadius( 5);	
	pLine->SetLineWidth(2);
	pLine->SetContoured(false); 
	pLine->SetColor(0.5,0,.5);
	pRegion->AddObject(pLine);

	pRegion->AddLegend();
	pRegion->GetAxe()->SetTitle(_T("Different markers"));
	pRegion->GetAxe()->GetBottomLabel().Hide();
	pRegion->GetAxe()->GetLeftLabel().Hide();	
}


void CPGLDemo::GetExampleBitmap(CPGLRegionPtr pRegion, LPCTSTR szFileName)
{
	using namespace gfxinterface;

	ASSERT(pRegion);
	pRegion->SetName(_T("Bitmaps"));

//	pRegion->Divide(2,1);

//	CPGLRegionPtr pChildRegion = pRegion->GetChild(0);
	CPGLRegionPtr pChildRegion = pRegion;
	CPGLImagePtr pImage = new CPGLImage;

		if ( !pImage->Load(szFileName))
		{
			AfxMessageBox(_T("Could not load image from file"));
			return;
		}
	pImage->GetArea().SetArea(1,1, CPGLArea2D::CoordNormClip);
	pImage->GetArea().SetPosition(0,0, CPGLCoord2D::Coord2DWorld);
	pImage->GetArea().SetAnchorType(CPGLArea2D::AnchorLowerLeft);	
	pChildRegion->AddObject(pImage);
	pChildRegion->GetAxe()->SetTitle(_T("Streched bitmap"));
/*
	pChildRegion = pRegion->GetChild(1);

	pImage = new CPGLImage;
	if ( !pImage->Load(IDB_BITMAP_DEMO ))
	{
		AfxMessageBox(_T("Could not load image from ressource"));
	}
	pImage->GetArea().SetPosition(SPointD(0.1,0.1), CPGLCoord2D::Coord2DNormClip);
	pImage->GetArea().SetAnchorType( CPGLArea2D::AnchorUpperLeft);
	pChildRegion->AddObject( pImage );
	pChildRegion->GetAxe()->GetTitle()->SetString(_T("Bitmap with constant width and height, anchor at upper left"));
*/
}

void CPGLDemo::GetExampleVectorField(CPGLRegionPtr pRegion)
{
	ASSERT(pRegion);
	pRegion->SetName(_T("Vector Field"));

	using namespace contour;

	int i,j;
	int nx=20;
	int ny=20;
	float dx=6.f/(nx-1);
	float dy=6.f/(ny-1);
	float vx,vy,x,y;
	std::vector<float> vX(nx*ny);
	std::vector<float> vY(nx*ny);

	CPGLMapVector* pVectorField = new CPGLMapVector;

	for (i=0;i<ny;i++)
	{
		y=(float)(i/(double)(ny-1));
		for (j=0;j<nx;j++)
		{
			x=j/(float)(nx-1);
			vx=(float)((DummyFieldFcn(x+dx/10,y)-DummyFieldFcn(x-dx/10,y))/(dx/5));
			vy=(float)((DummyFieldFcn(x,y+dy/10)-DummyFieldFcn(x,y-dy/10))/(dy/5));

			vX[i*nx+j]=vx;
			vY[i*nx+j]=vy;
		}
	}

	TQuadLinGridLattice<float>* pLattice = new TQuadLinGridLattice<float>(ny,nx,-3,3,dx,dy);

	// adding map
	pVectorField->SetLattice(pLattice);
	pVectorField->SetColor(0,0,0);
	pVectorField->SetLineWidth(1);
	pVectorField->SetDatas(vX,vY);
	pVectorField->SetName(_T("Vector map"));
	pRegion->AddObject(pVectorField);

	CPGLAxe2D* pAxis = pRegion->GetAxe();
	pAxis->SetTitle(_T("Vector field demo"));
}

void CPGLDemo::GetExampleSimpleLine(CPGLRegionPtr pRegion)
{
	using namespace gfxinterface;

	ASSERT_VALID(pRegion);
	pRegion->SetName(_T("A simple chart example"));

	// generate data
	UINT nPoints = 60;
	std::vector<double> vX(nPoints);
	std::vector<double> vY(nPoints);
	for (UINT i=0;i<nPoints;i++)
	{
		vX[i]=99.5+i/(double)nPoints;
		vY[i]=(1+sin(i/(double)nPoints*2*3.14)*1.1);
	}

	//Create a 2D line:
	CPGLLine2D* pLine = new CPGLLine2D();

	/*Attach the data to the line.
	*/
	pLine->SetDatas( vX /* x(i) */, vY /* y(i) */);

	//(Optional)Change some properties of the line:
	pLine->SetLineWidth(2);
	
	// setting name
	pLine->SetName(_T("A simple title"));
	pLine->SetShadowing(true);
	pLine->Set(_T("color=Red"));
	//Add the line to the graph (note that an object can be added to only one graph):
	pRegion->AddObject(pLine);

	pRegion->GetAxe()->GetBottomNumber().SetDescription(_T("%.6g"));
	// Changing the title
	pRegion->GetAxe()->SetTitle(_T("This is the title\n(All labels can have multiple lines)"));
	// changing the bottom label
	pRegion->GetAxe()->SetBottomLabel(_T("Bottom label\n(Position can be customized)"));
	// moving the bottom label
	pRegion->GetAxe()->GetBottomLabel().GetPosition().SetPosition( 0.7, 0, CPGLCoord2D::Coord2DNorm);
}

void CPGLDemo::GetExampleTextAnnotations(CPGLRegionPtr pRegion)
{
	using namespace gfxinterface;

	GetExampleSimpleLine( pRegion);

	CPGLTextPave* pTextPave = new CPGLTextPave(_T("This text annotation\ncan be placed anywhere( and it can be multi-line)"));
	{
		CPGLArea2D& area=pTextPave->GetArea();
		area.SetPosition( 0, 0, CPGLCoord2D::Coord2DNormClip);
		area.SetBBTrans( SPointD(10,10) );
		area.SetAnchorType( CPGLArea2D::AnchorLowerLeft);
		pRegion->AddObject( pTextPave );
	}

	CPGLText* pText = new CPGLText(_T("A text object can be placed anywhere."));
	{
		CPGLCoord2D& pos=pText->GetPosition();
		pos.SetPosition( 0, 1, CPGLCoord2D::Coord2DNormClip);
		pos.SetBBTrans( SPointD(20,-40) );
		pRegion->AddObject( pText );
	}

	pRegion->GetAxe()->SetTitle(_T("Text annotation demo"));
}

void CPGLDemo::GetExampleDashing(CPGLRegionPtr pRegion)
{
	using namespace gfxinterface;

	ASSERT_VALID(pRegion);
	pRegion->SetName(_T("Dashing patterns"));

	// generate data
	SPointD point;
	UINT nPoints = 60;
	std::vector<float> vX(nPoints);
	std::vector<float> vY(nPoints);
	for (UINT i=0;i<nPoints;i++)
	{
		vX[i]=(float)(i/(double)nPoints);
		vY[i]=(float)(1+sin(i/(double)nPoints*2*3.14)*1.1);
	}

	////////////////////////////////////////////////////////////
	// Continuous line
	//Create a 2D line:
	CPGLLine2DPtr pLine = new CPGLLine2D();

	/*Attach the data to the line. PGL will handle the memory afterwards. That is, it will delete 
	the pointers of data at the object destruction. This means <code>pX,pY</code> MUST have been 
	allocated on the heap !
	*/
	pLine->SetDatas( vX /* x(i) */, vY /* y(i) */);

	//(Optional)Change some properties of the line:
	pLine->SetLineWidth(2);

	pLine->SetName(_T("Continuous line"));
	//Add the line to the graph (note that an object can be added to only one graph):
	pRegion->AddObject(pLine);


	////////////////////////////////////////////////////////////
	// Dash line
	for (i=0;i<nPoints;i++)
	{
		vY[i]=(float)(1.1+sin(i/(double)nPoints*2*3.14)*1.1);
	}
	//Create a 2D line:
	pLine = new CPGLLine2D();
	pLine->SetDatas( vX /* x(i) */, vY /* y(i) */);
	pLine->SetLineWidth(2);
	pLine->SetDashPattern(PGL_LINE_BARBAR);
	pLine->SetName(_T("Dash line"));
	pRegion->AddObject(pLine);

	////////////////////////////////////////////////////////////
	// Dotted line
	for (i=0;i<nPoints;i++)
	{
		vY[i]=(float)(1.2+sin(i/(double)nPoints*2*3.14)*1.1);
	}
	//Create a 2D line:
	pLine = new CPGLLine2D();
	pLine->SetDatas( vX /* x(i) */, vY /* y(i) */);
	pLine->SetLineWidth(2);
	pLine->SetDashPattern(PGL_LINE_POINTPOINT);
	pLine->SetName(_T("A dotted line"));
	pRegion->AddObject(pLine);

	////////////////////////////////////////////////////////////
	// Dash dotted line
	for (i=0;i<nPoints;i++)
	{
		vY[i]=(float)(1.3+sin(i/(double)nPoints*2*3.14)*1.1);
	}
	//Create a 2D line:
	pLine = new CPGLLine2D();
	pLine->SetDatas( vX /* x(i) */, vY /* y(i) */);
	pLine->SetLineWidth(2);
	pLine->SetDashPattern(PGL_LINE_BARPOINT);
	pLine->SetName(_T("A dash-dotted line"));
	pRegion->AddObject(pLine);

	////////////////////////////////////////////////////////////
	// Custom dash line
	for (i=0;i<nPoints;i++)
	{
		vY[i]=(float)(1.4+sin(i/(double)nPoints*2*3.14)*1.1);
	}
	//Create a 2D line:
	pLine = new CPGLLine2D();
	pLine->SetDatas( vX /* x(i) */, vY /* y(i) */);
	pLine->SetLineWidth(2);
	pLine->SetDashPattern(_T("3 1 1 1 1 1"));
	pLine->SetName(_T("A custom dash line"));
	pRegion->AddObject(pLine);

	// Setting title and hiding grids, adding legend
	pRegion->AddLegend();
	pRegion->GetAxe()->SetTitle(_T("Different line dashing"));
	pRegion->GetAxe()->ShowHorGrid(false);
	pRegion->GetAxe()->ShowVerGrid(false);
	pRegion->GetAxe()->GetLeftLabel().Hide();
	pRegion->GetAxe()->GetBottomLabel().Hide();
}


void CPGLDemo::GetExampleClosing(CPGLRegionPtr pRegion)
{
	using namespace gfxinterface;

	ASSERT_VALID(pRegion);
	pRegion->SetName(_T("Line flags: Opened, closed, snapped to bottom."));

	// generate data
	SPointD point;
	
	UINT nPoints = 60;
	double d;
	std::vector<double> vX(nPoints);
	std::vector<double> vY(nPoints);

	////////////////////////////////////////////////////////////////////
	// adding legend
	CPGLLegend* pLegend = new CPGLLegend();
	CPGLRectD rBBox(0.7,0.1,1,0.2);
	point.x=1;
	point.y=0.1;
	pLegend->GetArea().SetAnchorType(CPGLArea2D::AnchorLowerRight);
	pLegend->GetArea().SetArea(rBBox, CPGLArea2D::CoordNorm);
	pLegend->GetArea().SetPosition(point, CPGLCoord2D::Coord2DNorm);
	point.x=-20;
	point.y=0;
	pLegend->GetArea().SetBBTrans(point);


	////////////////////////////////////////////////////////////////////
	// Closed line
	for (UINT i=0;i<nPoints;i++)
	{
		d=i/(double)(nPoints+1)*2*PGL_PI;
		vX[i]=cos(d);
		vY[i]=sin(d);
	}

	//Create a 2D line:
	CPGLLine2DPtr pLine = new CPGLLine2D();

	/*Attach the data to the line. PGL will handle the memory afterwards. That is, it will delete 
	the pointers of data at the object destruction. This means <code>pX,pY</code> MUST have been 
	allocated on the heap !
	*/
	pLine->SetDatas( vX /* x(i) */, vY /* y(i) */);

	//(Optional)Change some properties of the line:
	pLine->SetLineWidth(2);
	// Closing line
	pLine->SetOpen(false);
	pLine->SetName(_T("A closed line"));
	//Add the line to the graph (note that an object can be added to only one graph):
	pRegion->AddObject(pLine);
	pLegend->PushTop(pLine);

	////////////////////////////////////////////////////////////////////
	// Closed and filled line
	for (i=0;i<nPoints;i++)
	{
		d=i/(double)(nPoints+1)*2*PGL_PI;
		vX[i]=2.1+cos(d);
		vY[i]=sin(d);
	}
	//Create a 2D line:
	pLine = new CPGLLine2D();

	/*Attach the data to the line. PGL will handle the memory afterwards. That is, it will delete 
	the pointers of data at the object destruction. This means <code>pX,pY</code> MUST have been 
	allocated on the heap !
	*/
	pLine->SetDatas( vX /* x(i) */, vY /* y(i) */);

	//(Optional)Change some properties of the line:
	pLine->SetLineWidth(2);
	// Closing line
	pLine->SetOpen(false);
	pLine->SetFilled(true);
	pLine->SetName(_T("A closed and filled line"));
	// Create linear gradient...
	CPGLLinearGradientBrush* brush=new CPGLLinearGradientBrush(CPGLColor(1,.5,0), CPGLColor(0,.5,1),45);
	pLine->SetBrush(brush);
	//Add the line to the graph (note that an object can be added to only one graph):
	pRegion->AddObject(pLine);
	pLegend->PushTop(pLine);


	////////////////////////////////////////////////////////////////////
	// Filled and snap to bottom line
	for (i=0;i<nPoints;i++)
	{
		d=i/(double)(nPoints+1)*PGL_PI;
		vX[i]=4.1+cos(d);
		vY[i]=sin(d);
	}
	//Create a 2D line:
	pLine = new CPGLLine2D();

	/*Attach the data to the line. PGL will handle the memory afterwards. That is, it will delete 
	the pointers of data at the object destruction. This means <code>pX,pY</code> MUST have been 
	allocated on the heap !
	*/
	pLine->SetDatas( vX /* x(i) */, vY /* y(i) */);

	//(Optional)Change some properties of the line:
	pLine->SetLineWidth(2);
	// Closing line
	pLine->SetFilled(true);
	pLine->SetSnapBottom(true);
	pLine->SetName(_T("A filled, bottom snap line"));
	// Create linear gradient...
	CPGLLinearGradientBrush* brush2= new CPGLLinearGradientBrush(CPGLColor(0.1f,0,0.1f,.7f), CPGLColor(1,1,1),90);
	pLine->SetBrush(brush2);
	//Add the line to the graph (note that an object can be added to only one graph):
	pRegion->AddObject(pLine);
	pLegend->PushTop(pLine);

	pRegion->AddObject(pLegend);
	pRegion->GetAxe()->SetTitle(_T("Line states: open/close, filled, snap to bottom"));
	pRegion->GetAxe()->ShowHorGrid(false);
	pRegion->GetAxe()->ShowVerGrid(false);
	pRegion->GetAxe()->GetLeftLabel().Hide();
	pRegion->GetAxe()->GetBottomLabel().Hide();
}

void CPGLDemo::GetExampleLineLOD(CPGLRegionPtr pRegion)
{
	ASSERT_VALID(pRegion);
	CString str;
	// getting example 1
	GetExampleSimpleLine(pRegion);
	pRegion->SetName(_T("Line approximation"));


	// generate data
	UINT nPoints = 60;
	std::vector<double> vX(nPoints);
	std::vector<double> vY(nPoints);
	for (UINT i=0;i<nPoints;i++)
	{
		vX[i]=99.5+i/(double)nPoints;
		vY[i]=(1+sin(i/(double)nPoints*2*3.14)*1.1);
	}

	//Create a 2D line:
	CPGLLine2DLOD* pLineLOD = new CPGLLine2DLOD();

	pLineLOD->SetDatas( vX /* x(i) */, vY /* y(i) */);
	pLineLOD->GetHull().Shrink(6,0);

	pLineLOD->SetLineWidth(2);

	// changing color
	pLineLOD->SetColor(0,0,1);
	// showing box at approximation points
	pLineLOD->SetPointType(PGL_POINT_SQUARE);
	// setting diameter of box
	pLineLOD->SetPointWidth(4);

	pLineLOD->SetName(_T("A simple line with LOD"));

	// adding line
	pRegion->AddObject(pLineLOD);

	CPGLAxe2D* pAxis = pRegion->GetAxe();
	// Setting title
	str.Format(_T("Original curve: %d points, Approximated curve: %d points"), nPoints,pLineLOD->GetHull().GetKeySize());
	pAxis->SetTitle(str);
	pAxis->GetBottomLabel().Hide();
	pAxis->GetLeftLabel().Hide();	
}
void CPGLDemo::GetExampleDataHandling(CPGLRegionPtr pRegion)
{
	ASSERT_VALID(pRegion);
	pRegion->SetName(_T("Example of data types mixing"));

	using namespace std;

	// generate data
	UINT nPoints = 60;
	CPGLVectorD* pX=new CPGLVectorD(nPoints);
	CPGLVectorF* pY=new CPGLVectorF(nPoints);

	vector<double>& vX = pX->GetV();
	vector<float>& vY = pY->GetV();

	for (UINT i=0;i<nPoints;i++)
	{
		vX[i]=i/(double)nPoints;
		vY[i]=(float)(1+sin(i/(double)nPoints*2*3.14)*1.1)*10;
	}

	//Create a 2D line:
	CPGLLine2D* pLine = new CPGLLine2D();
	// Attaching data objects
	pLine->SetDatas(pX,pY);
	pLine->SetLineWidth(3);
	pLine->SetName(_T("(vector<double>, vector<float>)"));
	pRegion->AddObject(pLine);

	//Create a 2D line:
	pLine = new CPGLLine2D();
	// Creating a refenrec to vX
	CPGLVectorRefD* pRefX=new CPGLVectorRefD(vX);
	CPGLVectorF* pY2=new CPGLVectorF(vY);

	vY = pY2->GetV();
	for (i=0;i<nPoints;i++)
	{
		vY[i]+=5;
	}

	// attaching data object
	pLine->SetDatas(pRefX,pY2);
	pLine->SetLineWidth(2);
	pLine->SetColor(0.9f,0,0);
	pLine->SetName(_T("(vector<double>&, vector<float>)"));
	pRegion->AddObject(pLine);

	// creating another line...
	pLine = new CPGLLine2D();
	pLine->SetDatas( new CPGLVectorRefD(vX), new CPGLFcnData( &TestFunctionForFcnData , new CPGLVectorRefD(vX)) );
	pLine->SetColor(0,0,1);
	pLine->SetName(_T("(vector<double>&, fcn(vector<double>&))"));
	pRegion->AddObject(pLine);

	// Adding data made of pairs...
	m_vPairs.resize(nPoints);
	for (i=0;i<nPoints;i++)
	{
		m_vPairs[i].first=vX[i];
		m_vPairs[i].second=(int)floor(vY[i]);
	}
	pLine = new CPGLLine2D();
	pLine->SetDatas( new CPGLVectorPairRefDI(m_vPairs, true), new CPGLVectorPairRefDI( m_vPairs, false ));
	pLine->SetColor(0,0.5f,0);
	pLine->SetName(_T("vector<pair<double,int>>"));
	pLine->SetLineWidth(1.8f);
	pLine->SetInterpolationType( CPGLLine::InterpolationTypeStep);
	pRegion->AddObject(pLine);

	pRegion->AddLegend();

	pRegion->GetAxe()->SetTitle(_T("Playing with different data"));
}

void CPGLDemo::GetExampleHistogram(CPGLRegionPtr pRegion)
{
	using namespace std;
	using namespace gfxinterface;

	ASSERT(pRegion);
	pRegion->SetName(_T("Histogram"));
	CString str;

	UINT n=100000;
	// generating data...
	CRandomGenerator randn;
	CPGLValarrayF* pSamples = new CPGLValarrayF(n);
	valarray<float>& v=pSamples->GetV();

	for (UINT i = 0;i<pSamples->size();i++)
		v[i]= randn.RNOR();
	
	// creating histogram object
	CPGLHistogram* pHistogram = new CPGLHistogram();
	pHistogram->GetHistogram().Resize(50);
	pHistogram->SetValues( pSamples );
	pHistogram->SetName(_T("Histogram"));
	CPGLLinearGradientBrush* brush=new CPGLLinearGradientBrush( CPGLColor(.3f,.3f,.3f,.5f), CPGLColor(1,1,1), 45);
	pHistogram->SetBrush( brush);
	pHistogram->SetName(_T("Normal distribution histogram"));

	pRegion->AddObject( pHistogram );

	// adding theoretical curve...
	float fAve, fAdev, fSdev, fVar, fSkew, fKurt;
	// computing moments
	THistogram<float,float>::GetMoments( v, fAve, fAdev, fSdev, fVar, fSkew, fKurt);
	CPGLLine2D* pLine = new CPGLLine2D;
	str.Format(_T("exp( -(x - (%g))*(x - (%g))/(2*%g*%g) ) /(%g*sqrt(2*%g))"),
		fAve,fAve,fSdev,fSdev,fSdev,PGL_PI);
	// creating math data object
	CPGLMathFcnData* pMathData= new CPGLMathFcnData( 
		new CPGLLinearVector( pHistogram->GetHistogram().GetMinSpectrum(),
							  pHistogram->GetHistogram().GetStep(), pHistogram->GetHistogram().GetSize() )
							  );
	pMathData->Parse( str, _T("x"));
	pLine->SetDatas( new CPGLLinearVector( pHistogram->GetHistogram().GetMinSpectrum(),
		pHistogram->GetHistogram().GetStep(), pHistogram->GetHistogram().GetSize()),
		pMathData);
	pLine->SetColor( 1,0,0);
	pLine->SetLineWidth(2);
	pLine->SetName(_T("Theoretical distribution with computed moments"));
//	pRegion->AddObject(pLine);

	// adding legend
	pRegion->AddLegend();// CPGLLegend::LegendPosLowerRight );

	// changing title
	CPGLAxe2D* pAxis = pRegion->GetAxe();
	str.Format(_T("Histogram of normal variable generator (%u points)"), pSamples->size());
	pAxis->SetTitle(str);
}


void CPGLDemo::GetExampleTimeLabel(CPGLRegionPtr pRegion)
{
	ASSERT(pRegion);
	pRegion->SetName(_T("Time labelling"));
	COleDateTime tStart(2000,1,1,22,30,0);
	COleDateTime tNow;
	COleDateTimeSpan halfhour(0,0,30,0); 
	COleDateTimeSpan t1minutes12seconds(0,0,1,12); 
	COleDateTimeSpan second(0,0,0,1); 
	COleDateTimeSpan dt;

	// generating data
	UINT nPoints = 128;
	std::vector<double> vT(nPoints);
	std::vector<double> vY(nPoints);

	tNow = tStart;
	for (UINT i=0;i<nPoints;i++)
	{
		dt = tNow - tStart;
		vT[i] = dt.GetTotalSeconds();
		vY[i] = sin(i/(double)nPoints*2*3.14);

		tNow+=t1minutes12seconds;
	}

	// create and add line
	CPGLLine2D* pLine = new CPGLLine2D;
	pLine->SetDatas(vT, vY);
	pRegion->AddObject(pLine);

	CPGLAxe2D* pAxis = pRegion->GetAxe();
	// setting time label
	pAxis->SetTimeLabel(TRUE);
	pAxis->SetTimeLabelFormat(tStart
		 /* Time at coordinate zero. */, 
			second	/* Time per unit */,
			_T("%d,%H:%M") /* String format */);
	pAxis->GetBottomNumber().SetAngle(-45);
	pAxis->GetBottomNumber().SetAlign(gfxinterface::TextAlignmentLeft);


	// fix labelling
	pAxis->SetAutoSteps(CPGLAxe2D::AxisHorizontal,false);
	pAxis->SetGridStep(CPGLAxe2D::AxisHorizontal, halfhour.GetTotalSeconds());
}

void CPGLDemo::GetExampleStackedLines(CPGLRegionPtr pRegion)
{
	ASSERT_VALID(pRegion);
	pRegion->SetName(_T("Stacked lines"));

	// generate data
	UINT nPoints = 6;
	std::vector<float> vX(nPoints);
	std::vector<float> vY(nPoints);
	std::vector<float> vY1(nPoints);
	std::vector<float> vY2(nPoints);
	for (UINT i=0;i<nPoints;i++)
	{
		vX[i]=(float)(i/(double)(nPoints-1));
		vY[i]=(float)(0.2+0.8*vX[i]*vX[i]);
		vY1[i]=(float)(0.6*(1-vX[i])+0.2*vX[i]);
		vY2[i]=(float)(0.3+((1-vX[i])*0.6+0.4)*(1-vX[i]));
	}

	//Create a 2D line:
	CPGLStackedLine2DPtr pStackedLines = new CPGLStackedLine2D;
	pStackedLines->SetX(vX);

	pStackedLines->SetName(_T("Stacked lines"));
	pStackedLines->SetDescription(_T("A legend string"));

	CPGLLine1DPtr pLine = new CPGLLine1D;
	pLine->SetName(_T("Bottom line"));
	pLine->SetValues(vY);
	//(Optional)Change some properties of the line:
	pLine->SetSolidFillColor(CPGLColor(0.7f,0.2f,0.2f,0.3f));
	pLine->SetColor(0,0,0);
	pLine->SetLineWidth(0.5);
	pStackedLines->PushTop(pLine);

	pLine = new CPGLLine1D;
	pLine->SetName(_T("Middle line"));
	pLine->SetValues(vY1);
	//(Optional)Change some properties of the line:
	pLine->SetSolidFillColor(CPGLColor(0.5f,0.2f,0.5f,0.3f));
	pLine->SetColor(0.2f,0.1f,0.7f);
	pLine->SetLineWidth(0.5);
	pStackedLines->PushTop(pLine);

	pLine = new CPGLLine1D;
	pLine->SetName(_T("Top line"));
	pLine->SetValues(vY2);
	pLine->SetSolidFillColor(CPGLColor(0.2f,0.1f,0.9f,0.3f));
	pLine->SetLineWidth(0.5);
	pLine->SetPointType(PGL_POINT_SQUARE);
	pLine->SetPointWidth(5);
	pLine->SetColor(0,0,0);
	pLine->SetShadowing();
	pStackedLines->PushTop(pLine);

	//Add the line to the graph (note that an object can be added to only one graph):
	pRegion->AddObject(pStackedLines);
	pRegion->AddLegend();

	pRegion->GetAxe()->SetTitle(_T("Stacked Lines"));
	pRegion->GetAxe()->GetHorGrid().Hide();
	pRegion->GetAxe()->GetVerGrid().Hide();
}

float DummyFieldFcn( float x, float y)
{
	return (float)(3*pow((1-x),2)*exp(-pow(x,2) - pow((y+1),2)) 
   - 10*(x/5.0 - pow(x,3) - pow(y,5))*exp(-pow(x,2)-pow(y,2))
   - 1/3*exp(-pow((x+1),2) - pow(y,2)));
}

void CPGLDemo::GetExampleMaps(CPGLRegionPtr pRegion)
{
	ASSERT_VALID(pRegion);
	pRegion->SetName(_T("Maps and contour"));
	using namespace contour;

	int i,j;
	int nPlanes=10;
	int nx=30;
	int ny=30;
	float x,y;
	float dx=8.f/(nx-1);
	float dy=8.f/(ny-1);

	CPGLAxe2D* pAxis=pRegion->GetAxe();
	pAxis->SetTitle(_T("Color maps and contours"));

	// height map and contour
	CPGLMapContour* pMapContour=new CPGLMapContour();
	TQuadLinGridLattice<float>* pLattice = new TQuadLinGridLattice<float>( ny,nx,-4,4,dx,dy);
	pMapContour->SetLattice(pLattice);
	pMapContour->SetField(new TFieldFcn<float>(DummyFieldFcn));
	std::vector<float> vPlanes(nPlanes);
	for (i=0;i<nPlanes;i++)
	{
		vPlanes[i] = (float)(-6+i/(double)nPlanes*14.0);
	}
	pMapContour->SetPlanes(vPlanes);
	pMapContour->SetName(_T("Height, Contour map"));
	pMapContour->GetContour().SetFirstGrid(ny,nx);
	pMapContour->GetContour().SetSecondaryGrid(ny*4,nx*4);
	pMapContour->GenerateContours();
	pMapContour->ShowWireFrame(false);
	pRegion->AddObject(pMapContour);

	// Simple height map
	CPGLMapZ* pMapZ = new CPGLMapZ;
	pMapZ->SetName(_T("Height map, FieldRegMap"));
	TQuadLinGridLattice<float>* pZLattice = new TQuadLinGridLattice<float>( ny,nx,4,4,dx,dy);
	pMapZ->SetLattice(pZLattice);
	TFieldRegMap<float>* pFieldRegMap=new TFieldRegMap<float>;
	TFieldMap<float>::Matrix& z=pFieldRegMap->GetMap();
	z.resize( ny, nx);

	double m=std::numeric_limits<double>::infinity();
	double n=-std::numeric_limits<double>::infinity();
	for (i=0;i<ny;i++)
	{
		y=(float)(4.0-i*dy);
		for (j=0;j<nx;j++)
		{
			x=(float)(-4.0+j*dx);
			z(i,j)=DummyFieldFcn(x,y);
			m=__min(z(i,j),m);
			n=__max(z(i,j),n);
		}
	}

	pMapZ->SetField(pFieldRegMap,true);
	pMapZ->SetColorMap(CPGLUtility::ColorMapHot);
	pRegion->AddObject(pMapZ);

}

void CPGLDemo::GetExampleDifferentFills(CPGLRegionPtr pRegion)
{
	ASSERT(pRegion);
	pRegion->SetName(_T("Solid, linear gradient and Texture fill."));

	// generate data
	int i,nPoints = 50;
	std::vector<double> vX(nPoints);
	std::vector<double> vY(nPoints);
	double	radius = 1;

	for (i=0;i<nPoints;i++)
	{
		vX[i]=radius*cos(i/(double)nPoints*2*PGL_PI);
		vY[i]=radius*sin(i/(double)nPoints*2*PGL_PI);
	}

	//Create a 2D line with solid fill
	CPGLLine2D* pLine = new CPGLLine2D();
	pLine->SetName(_T("Solid Fill brush"));
	pLine->SetDatas(vX,vY);
	pLine->SetSolidFillColor(1,0,0,0.8f);
	pLine->SetFilled(true);
	pLine->SetOpen(false);
	pLine->SetTension(0.2);
	pRegion->AddObject(pLine);

	for (i=0;i<nPoints;i++)
	{
		vX[i]=radius*4.2+radius*cos(i/(double)nPoints*2*PGL_PI);
		vY[i]=radius*sin(i/(double)nPoints*2*PGL_PI);
	}

	pLine = new CPGLLine2D();
	pLine->SetName(_T("Linear gradient brush"));
	pLine->SetDatas(vX,vY);
	CPGLLinearGradientBrush* linear=new CPGLLinearGradientBrush( CPGLColor(0.6f,0.6f,0.8f), CPGLColor(1,1,1,0.5), 90);
	pLine->SetBrush(linear);
	pLine->SetFilled(true);
	pLine->SetOpen(false);
	pLine->SetTension(0.2);
	pRegion->AddObject(pLine);


	//Create a 2D line with texture brush
	for (i=0;i<nPoints;i++)
	{
		vX[i]=radius*2.1+radius*cos(i/(double)nPoints*2*PGL_PI);
		vY[i]=.5*radius*sin(i/(double)nPoints*2*PGL_PI);
	}
	pLine = new CPGLLine2D();
	CPGLTextureBrush* tex=new CPGLTextureBrush;
	tex->Load(_T("testImage.jpg"));
	pLine->SetName(_T("Texture brush"));
	pLine->SetDatas(vX,vY);
	pLine->SetBrush(tex);
	pLine->SetFilled(true);
	pLine->SetOpen(false);
	pLine->SetTension(0.2);

	pRegion->AddObject(pLine);

	pRegion->AddLegend();
}


float TestFunctionForFcnData( float f)
{
	return (float)(sin(2*f*3.14)+0.3f)*10;
}

void CPGLDemo::GetExampleAxis(CPGLRegionPtr pRegion)
{
	ASSERT_VALID(pRegion);
	pRegion->SetName(_T("Axis Customization"));
	GetExampleLineLOD(pRegion);

	//////////////////////////////////////////////////////////////////////////////////////
	///
	/// Customizing the axis:
	// getting pointer to the axis
	CPGLAxe2D* pAxis = pRegion->GetAxe();

	// changing bckground
	CPGLLinearGradientBrush* brush=new CPGLLinearGradientBrush( CPGLColor(.8f,.8f,1), CPGLColor(1,1,1,1), 45);
	pAxis->SetBrush(brush);

	// Changing the title
	// Setting title
	CString str;
	str.Format(_T("A modified title, Arial - Bold, size 14"));
	pRegion->SetName(str);
	pAxis->SetTitle(str);
	pAxis->GetTitle().SetColor(0,0.5f,0);

	// changing title font
	LOGFONT lf=pAxis->GetTitle().GetFont().GetLOGFONT();
	lf.lfWeight=FW_BOLD;
	lf.lfHeight=14;
	_tcscpy(lf.lfFaceName,_T("Arial"));
	pAxis->GetTitle().GetFont().SetLOGFONT(lf);

	// setting grid off
	pAxis->ShowHorGrid(false);
	pAxis->ShowVerGrid(false);

	// setting time label
	pAxis->SetTimeLabel(true);
	pAxis->SetTimeLabelFormat(COleDateTime(2000,1,1,12,0,0) /* Time at zero. */, 
			COleDateTimeSpan(0,0,30,0)	/* Time per unit */,
			_T("%H:%M") /* String format */);

	// rotating text so it does not override
	pAxis->GetBottomNumber().SetAngle(-45);
	pAxis->GetBottomNumber().SetAlign(gfxinterface::TextAlignmentLeft);

	pAxis->GetTopNumber().Show();
	pAxis->GetRightNumber().Show();

	// changing ticks
	pAxis->SetAllSecondTicksNb(5);
	pAxis->SetAllSecondTicksSize(3);

	// hiding right and top
	pAxis->SetRightMainTicksSize(0);
	pAxis->SetTopMainTicksSize(0);
	pAxis->SetRightSecondTicksSize(0);
	pAxis->SetTopSecondTicksSize(0);

	// hide outside square...
	pAxis->SetBorderLineVisibility( CPGLRectB(false, false, false, false));

	// hiding bottom label
	pAxis->GetBottomLabel().Show(false);
	pAxis->GetLeftLabel().Show(false);

	// chaging color and width
	pAxis->GetBorderStyle().SetLineWidth(0.5);
	pAxis->GetBorderStyle().SetDashPattern(_T("5 10"));

	// moving axis
	pAxis->SetNumberPos(CPGLAxe2D::ENumberingLeft, 0.5);
	pAxis->SetNumberPos(CPGLAxe2D::ENumberingBottom, 0.5);
}

void CPGLDemo::GetExampleSubplot(CPGLRegionPtr pRegion)
{
	ASSERT_VALID(pRegion);

//	pRegion->Divide(2,1);

	pRegion->Layout(
		_T(
"<layout>\
	<matrix nrows=\"2\"  ypos=\"1 0.33 0\">\
		<child index=\"1\">\
			<matrix ncols=\"3\"  xpos=\"0 0.25 0.5 1\"/>\
		</child>\
	</matrix>\
</layout>"));

	CPGLRegionPtr pChildRegion;
	// divide graph : waring this functions will delete all objects of the graph
	pRegion->SetName(_T("Subplotting"));

	// iterating over childs
	// adding first example
	pChildRegion = pRegion->GetChild(0);
	ASSERT(pChildRegion);
	pChildRegion->SetBorderType(CPGLPave::BorderLowerRightShadow);
	GetExampleScatter(pChildRegion);
	
	// adding second example 
	pChildRegion = pRegion->GetChild(1);
	ASSERT(pChildRegion);
	pChildRegion->SetBorderType(CPGLPave::BorderLowerRightShadow);
	GetExampleLineLOD(pChildRegion);

	// adding thrid example
	pChildRegion = pRegion->GetChild(2);
	ASSERT(pChildRegion);
	pChildRegion->SetBorderType(CPGLPave::BorderLowerRightShadow);
	GetExampleSplines(pChildRegion);	

	// adding fourth example 
	pChildRegion = pRegion->GetChild(3);
	ASSERT(pChildRegion);
	pChildRegion->SetBorderType(CPGLPave::BorderLowerRightShadow);
	GetExampleMarkers(pChildRegion);
	
}

void CPGLDemo::GetArchiveDemo(LPCTSTR szFileName)
{
	CPGLRegionPtr pRegion = new CPGLRegion;

	// drawing stuff
	GetExampleSplines( pRegion );

	// creating archive
	CPGLArchive ar( pRegion );

	// setting string
	CString str;
	str.Format(_T("Testing CPGLArchive Output with name %s"), szFileName);
	ar.SetTextOverlay(str);

	// outputing...
	ar.SetJPEGQuality(70);
	CPGLPointU dim(640,480);

	ar.ExportToFile( CPGLArchive::FileFormatPNG,szFileName,dim,NULL,true);
	ar.ExportToFile( CPGLArchive::FileFormatJPG,szFileName,dim);
	ar.ExportToFile( CPGLArchive::FileFormatTIFF,szFileName,dim);
	ar.ExportToFile( CPGLArchive::FileFormatBMP,szFileName,dim);
	ar.ExportToFile( CPGLArchive::FileFormatEMFPlusDual,szFileName,dim);
	ar.ExportToFile( CPGLArchive::FileFormatEPS,szFileName,dim);
	ar.ExportToFile( CPGLArchive::FileFormatSVG,szFileName,dim);

}


HRESULT CPGLDemo::GetEmfToIStreamDemo(LPCTSTR szFileName)
{
	USES_CONVERSION;

	CPGLRegionPtr pRegion = new CPGLRegion;

	// drawing stuff
	GetExampleSplines( pRegion );

	// creating archive
	CPGLArchive ar( pRegion );

	// setting string
	CString str;
	str.Format(_T("Testing CPGLArchive Output with name %s"), szFileName);
	ar.SetTextOverlay(str);

	// outputing...
	CPGLPointU dim(640,480);

	IStorage* pStorage=NULL;
	IStream* pStream=NULL;
	HRESULT hr;

	hr=::StgCreateDocfile(
		T2CW(szFileName),   //Pointer to path of compound file 
                           // to create
		STGM_CREATE | STGM_WRITE | STGM_SHARE_EXCLUSIVE ,           //Specifies the access mode for 
                           // opening the storage object
		0,          //Reserved; must be zero
		&pStorage     //Pointer to location for 
                           // returning the new storage object
		);
	if (FAILED(hr))
		goto Cleaning;

	hr=pStorage->CreateStream(
		L"pglChart",   //Pointer to the name of the new stream
		STGM_CREATE | STGM_WRITE | STGM_SHARE_EXCLUSIVE,           //Access mode for the new stream
		0,         //Reserved; must be zero
		0,         //Reserved; must be zero
		&pStream          //Pointer to new stream object
	);
	if (FAILED(hr))
		goto Cleaning;

	ar.ExportToStream( CPGLArchive::FileFormatEMFPlusDual,pStream,dim);	

Cleaning:
	if (pStorage)
		pStorage->Release();
	if (pStream)
		pStream->Release();

	return hr;
}


void CPGLDemo::GetExampleHistogram1(CPGLRegionPtr pRegion, int n) 
{ 
	using namespace gfxinterface;
	ASSERT(pRegion); 
	
	pRegion->SetName(_T("Histograms")); 
	
	UINT i; 
	CRandomGenerator randn; 
	CPGLVectorFPtr pSamples1 = new CPGLVectorF(n); 
	
	for (i = 0;i<pSamples1->size();i++) 
		(*pSamples1)[i]= randn.RNOR(); 
	
	CPGLHistogram* pHistogram1 = new CPGLHistogram(CPGLColor(0,0,0,1), CPGLColor(1,0,0,0.5)); 
	pHistogram1->GetHistogram().Resize(10); 
	{
		CPGLHistogram::Histogram& histo=pHistogram1->GetHistogram();
		histo.SetMinSpectrum(-5);
		histo.SetMaxSpectrum(5);
	}
	pHistogram1->SetValues(pSamples1,false);
	
	CPGLAxe2D* pAxe = pRegion->GetAxe(); 	
	pAxe->SetTitle( _T("A title\r\nthas has multiple lines") ); 
//	pAxe->SetLabel( CPGLAxe2D::ELabelLeft, CPGLText("RNOR") ); 
	
	pRegion->AddObject( pHistogram1 ); 
}

#define PGLDEMO_RENDER_FILE( fileName) \
	str.Format(_T("Generating %s"), _T( #fileName )); \
	pRegion=RenderExample(_T(#fileName));\
	ar.SetRegion(pRegion);\
	ar.ExportToFile( eFileFormat, _T(#fileName), dim, NULL, true);\
	CPGLUtility::PeekAndPump();


void CPGLDemo::GetAllExamples( CPGLArchive::EFileFormat eFileFormat, const CPGLPointU& dim)
{
	CPGLRegionPtr pRegion;
	CPGLArchive ar;
	CString str;

	PGLDEMO_RENDER_FILE( axis  );
	PGLDEMO_RENDER_FILE( bar );
	PGLDEMO_RENDER_FILE( closing );
	PGLDEMO_RENDER_FILE( container );
	PGLDEMO_RENDER_FILE( dashing );
	PGLDEMO_RENDER_FILE( data );
	PGLDEMO_RENDER_FILE( fills );
	PGLDEMO_RENDER_FILE( histogram );
	PGLDEMO_RENDER_FILE( histogram2 );
	PGLDEMO_RENDER_FILE( legend );
	PGLDEMO_RENDER_FILE( interpolation );
	PGLDEMO_RENDER_FILE( lod );
	PGLDEMO_RENDER_FILE( maps );
//	PGLDEMO_RENDER_FILE( multiaxis );
	PGLDEMO_RENDER_FILE( pie );
	PGLDEMO_RENDER_FILE( scatter );
	PGLDEMO_RENDER_FILE( spline );
	PGLDEMO_RENDER_FILE( stacked );
	PGLDEMO_RENDER_FILE( stock );
	PGLDEMO_RENDER_FILE( time );
	PGLDEMO_RENDER_FILE( vector );
	PGLDEMO_RENDER_FILE( simple );
	PGLDEMO_RENDER_FILE( markers );
	PGLDEMO_RENDER_FILE( errorbar );
	PGLDEMO_RENDER_FILE( text );

	pRegion=RenderExample(_T("subplot"));
	ar.SetRegion(pRegion);
	ar.ExportToFile( eFileFormat, _T("subplot"), CPGLPointU(1920,1440), NULL, true);
}

CPGLRegionPtr CPGLDemo::RenderExample( LPCTSTR szDemo)
{
	CString sDemo(szDemo);
	CPGLRegionPtr pRegion = new CPGLRegion;

	sDemo.MakeLower();
	if (sDemo == _T("axis"))
		GetExampleAxis(pRegion);
	else if (sDemo == _T("bar"))
		GetExampleBar(pRegion);
	else if (sDemo == _T("closing"))
		GetExampleClosing(pRegion);
	else if (sDemo == _T("container"))
		GetExampleContainer(pRegion);
	else if (sDemo == _T("dashing"))
		GetExampleDashing(pRegion);
	else if (sDemo == _T("data"))
		GetExampleDataHandling(pRegion);
	else if (sDemo == _T("fills"))
		GetExampleDifferentFills(pRegion);
	else if (sDemo == _T("histogram"))
		GetExampleHistogram(pRegion);
	else if (sDemo == _T("histogram2"))
		GetExampleHistogram1(pRegion,1);
	else if (sDemo == _T("interpolation"))
		GetExampleLineInterpolation(pRegion);
	else if (sDemo == _T("lod"))
		GetExampleLineLOD(pRegion);
	else if (sDemo == _T("maps"))
		GetExampleMaps(pRegion);
	else if (sDemo == _T("markers"))
		GetExampleMarkers(pRegion);
	else if (sDemo == _T("multiaxis"))
		GetExampleMultipleAxis(pRegion);
	else if (sDemo == _T("pie"))
		GetExamplePie(pRegion);
	else if (sDemo == _T("scatter"))
		GetExampleScatter(pRegion);
	else if (sDemo == _T("spline"))
		GetExampleSplines(pRegion);
	else if (sDemo == _T("stacked"))
		GetExampleStackedLines(pRegion);
	else if (sDemo == _T("stock"))
		GetExampleStock(pRegion);
	else if (sDemo == _T("subplot"))
		GetExampleSubplot(pRegion);
	else if (sDemo == _T("time"))
		GetExampleTimeLabel(pRegion);
	else if (sDemo == _T("vector"))
		GetExampleVectorField(pRegion);
	else if (sDemo == _T("subplot"))
		GetExampleSubplot(pRegion);
	else if (sDemo == _T("errorbar"))
		GetExampleErrorBar(pRegion);
	else if (sDemo == _T("text"))
		GetExampleTextAnnotations(pRegion);
	else 
		GetExampleSimpleLine(pRegion);

	return pRegion;
}

UINT CPGLDemo::ThreadProc( LPVOID pParam )
{
    CPGLDemo* me= (CPGLDemo*)pParam;
    me->Threading();
    return 0;
}

void CPGLDemo::Threading()
{
	// generate data...

}

void CPGLDemo::GetExampleErrorBar(CPGLRegionPtr pRegion)
{
	ASSERT_VALID(pRegion);
	UINT i;
	pRegion->SetName(_T("Error bars"));


	srand((unsigned)time( NULL ));

	// generate data
	CPGLColor col;
	UINT nPoints = 10;
	std::vector<float> vX(nPoints);
	std::vector<float> vY(nPoints);
	std::vector<float> vEUp(nPoints);
	std::vector<float> vEDown(nPoints);

	// Absolute vertical...
	CPGLErrorBar* pLine = new CPGLErrorBar();
	for (i=0;i<nPoints;i++)
	{
		vX[i]=(float)(i/(double)nPoints);
		vY[i]=(float)((1+sin(vX[i]*PGL_PI/2)*1.1));
		vEUp[i]=(float)(vY[i]+rand()/(double)RAND_MAX*0.4);
		vEDown[i]=(float)(vY[i]-rand()/(double)RAND_MAX*0.4);
	};
	pLine->SetDatas( vX /* x(i) */, vY /* y(i) */);
	pLine->SetErrorDatas(vEUp, vEDown);
	pLine->SetLineWidth(1.5);
	pLine->SetName(_T("Absolute, vertical"));
	pLine->SetShadowing(true);
	CPGLUtility::HSV( 0.3, col);
	pLine->SetColor(0,0,1);
	pRegion->AddObject(pLine);
	
	// Relative vertical...
	for (i=0;i<nPoints;i++)
	{
		vX[i]=(float)(1+i/(float)nPoints);
		vY[i]=(float)((1+sin(vX[i]*PGL_PI/2)*1.1));
		vEUp[i]=rand()/(float)RAND_MAX*0.4f;
		vEDown[i]=rand()/(float)RAND_MAX*0.4f;
	}
	pLine = new CPGLErrorBar();
	pLine->SetDatas( vX /* x(i) */, vY /* y(i) */);
	pLine->SetErrorDatas(vEUp, vEDown);
	pLine->SetAbsolute(false);
	pLine->SetLineWidth(1);
	pLine->SetName(_T("Relative, vertical"));
	pLine->SetShadowing(true);
	pLine->SetColor(0,0.6f,0);
	pLine->SetMarkerType(CPGLLine::MarkerTypeCircle);
	pRegion->AddObject(pLine);

	// Absolute horizontal...
	pLine = new CPGLErrorBar();
	for (i=0;i<nPoints;i++)
	{
		vX[i]=(float)(2+i/(double)nPoints);
		vY[i]=(float)((1+sin(vX[i]*PGL_PI/2)*1.1));
		vEUp[i]=(float)(vX[i]+rand()/(double)RAND_MAX*0.2);
		vEDown[i]=(float)(vX[i]-rand()/(double)RAND_MAX*0.2);
	};
	pLine->SetDatas( vX /* x(i) */, vY /* y(i) */);
	pLine->SetErrorDatas(vEUp, vEDown);
	pLine->SetVertical(false);
	pLine->SetLineWidth(2);
	pLine->SetName(_T("Absolute, horizontal"));
	pLine->SetShadowing(true);
	pLine->SetColor(1,0,0);
	pRegion->AddObject(pLine);


	// Relative horizontal...
	pLine = new CPGLErrorBar();
	for (i=0;i<nPoints;i++)
	{
		vX[i]=(float)(3+i/(double)nPoints);
		vY[i]=(float)((1+sin(vX[i]*PGL_PI/2)*1.1));
		vEUp[i]=(float)(rand()/(double)RAND_MAX*0.2);
		vEDown[i]=(float)(rand()/(double)RAND_MAX*0.2);
	};
	pLine->SetDatas( vX /* x(i) */, vY /* y(i) */);
	pLine->SetErrorDatas(vEUp, vEDown);
	pLine->SetAbsolute(false);
	pLine->SetVertical(false);
	pLine->SetLineWidth(2);
	pLine->SetName(_T("Relative, horizontal"));
	pLine->SetShadowing(true);
	pLine->SetShowLine(true);
	pLine->SetColor(0,0,0);
	pRegion->AddObject(pLine);

	pRegion->AddLegend();
	pRegion->GetAxe()->SetTitle(_T("Error bars"));
}
